#include "Message.h"
#include <QLabel>
#include <QPainter>
#include <QMouseEvent>
#include <QHBoxLayout>
#include <QMainWindow>
#include <QPropertyAnimation>
#include <QDebug>

void CloseButton::setMsgType(MsgType msgType)
{
    m_msgType=msgType;
}

MsgType CloseButton::getMsgType() const
{
    return m_msgType;
}

void CloseButton::setOpacity(qreal opacity)
{
    m_opacity=opacity;
//    update();
}

qreal CloseButton::getOpacity() const
{
    return m_opacity;
}

QColor CloseButton::backgroundColor(MsgType msgType)
{
    switch (msgType) {
#define CREATE_COLOR(E,S,C1,C2,C3) case MsgType::E : {return C1;}
    FOR_ALL_MSG_TYPE(CREATE_COLOR)
#undef CREATE_COLOR
    }
    return backgroundColor(MsgType::Unknow);
}

void CloseButton::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton){
        emit clicked();
    }
    QWidget::mousePressEvent(event);
}

void CloseButton::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    QRect contentRect=this->rect().adjusted(13,13,-13,-13);

    /*绘制背景*/
    QColor brushColor = backgroundColor(m_msgType);
    brushColor.setAlpha(brushColor.alpha()*m_opacity);
    painter.setPen(Qt::NoPen);
    painter.setBrush(brushColor);
    painter.drawEllipse(this->rect());

    /**/
    painter.setBrush(Qt::NoBrush);
    QPen pen(Qt::white,6);
    pen.setCapStyle(Qt::RoundCap);
    painter.setPen(pen);
    if(m_msgType==MsgType::Info){ /*绘制√*/
        QPoint p1(contentRect.x()-3,(contentRect.y()+contentRect.height())/2+3);
        QPoint p2((contentRect.x()+contentRect.width())/2+3,contentRect.y()+contentRect.height());
        QPoint p3(contentRect.x()+contentRect.width(),contentRect.y());
        QPoint points[3]={p1,p2,p3};
        painter.drawPolyline(points,3);
    }else{ /*绘制x*/
        painter.drawLine(contentRect.topLeft(),contentRect.bottomRight());
        painter.drawLine(contentRect.topRight(),contentRect.bottomLeft());
    }
}

void StyleLabel::setMsgType(MsgType msgType)
{
    m_msgType=msgType;
}

MsgType StyleLabel::getMsgType() const
{
    return m_msgType;
}

void StyleLabel::setOpacity(qreal opacity)
{
    m_opacity=opacity;
//    update();
}

qreal StyleLabel::getOpacity() const
{
    return m_opacity;
}

void StyleLabel::setText(const QString& text)
{
    m_text = text;
}

QString StyleLabel::getText() const
{
    return m_text;
}

void StyleLabel::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    /*绘制背景*/
    painter.setPen(Qt::NoPen);
    QColor bgColor=CloseButton::backgroundColor(m_msgType);
    bgColor.setAlpha(bgColor.alpha()*m_opacity);
    painter.setBrush(bgColor);
    painter.drawRoundedRect(this->rect().adjusted(5,5,-5,-5),5,5);

    /**/
    QColor ftColor=Message::fontColor(m_msgType);
    painter.setFont(this->font());
    painter.setPen(ftColor);
    painter.drawText(this->rect(),Qt::AlignCenter,m_text);
}

//-----------------------------------------------------------
Message::Message(QWidget *parent) : QWidget(parent)
{
    /*设置窗体无边框、置顶、关闭时自动析构*/
    setAttribute(Qt::WA_DeleteOnClose,true);
    setWindowFlag(Qt::WindowStaysOnTopHint,true);
    setWindowFlag(Qt::FramelessWindowHint,true);

    /*最小宽度*/
    this->setMinimumWidth(300);

    /*文本*/
    m_label=new QLabel(this);
//    m_label->setWordWrap(true); /*不建议自动换行，由用户自行控制是否换行*/
    m_label->setAlignment(Qt::AlignCenter);
    m_label->setFont(QFont("微软雅黑",13,75));
    m_label->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

    /*类型*/
    m_typeLabel=new StyleLabel(this);
    m_typeLabel->setFont(QFont("微软雅黑",11,75));
    QFontMetrics ftm(m_typeLabel->font());
    int w =ftm.horizontalAdvance(toString(MsgType::Unknow));
    int h =ftm.height();
    m_typeLabel->setFixedSize(w+25,h+15);

    m_typeLabel->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);

    /*关闭按钮*/
    m_button=new CloseButton(this);
    m_button->setFixedSize(43,43);    /*固定尺寸*/
    m_button->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);

    /*布局管理器*/
    QHBoxLayout* hLayot=new QHBoxLayout(this);
    hLayot->setContentsMargins(4,4,4,4);
    hLayot->addWidget(m_typeLabel);
    hLayot->addWidget(m_label);
    hLayot->addWidget(m_button);

    /*窗体透明度变化属性动画*/
    QPropertyAnimation* animation=new QPropertyAnimation(this,"opacity",this);
    animation->setStartValue(1.0);
    animation->setEndValue(0.2);
    animation->setDuration(/*std::chrono::seconds(5)*/5000);
    animation->start(/*QPropertyAnimation::DeleteWhenStopped*/);    /*由父对象管理(动画停止、自动析构)*/
    connect(animation,&QPropertyAnimation::finished,this,&Message::close);  /*动画完毕时关闭窗口*/

    /*点击关闭按钮弹窗消失*/
    connect(m_button,&CloseButton::clicked,this,&Message::close);
}

Message::~Message()
{

}

void Message::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    /*绘制背景*/
    QColor brushColor = backgroundColor(m_msgType);
    brushColor.setAlpha(brushColor.alpha()*m_opacity);

    painter.setPen(Qt::NoPen);
    painter.setBrush(brushColor);
    painter.drawRoundedRect(this->rect(),8,8);
}

bool Message::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type()==QEvent::Resize) {
        this->move(parentWidget()->width()/2-this->width()/2,10);
//        return true;
    }

    return QWidget::eventFilter(obj, event);
}

void Message::showMessage(const QString& msg,MsgType type,QWidget* w)
{
    /*判空*/
    QWidget* topLevelWidget=w->topLevelWidget();
    if(!(w && topLevelWidget)){
        return;
    }
    if(auto mainWindow = dynamic_cast<QMainWindow*>(topLevelWidget)){
        topLevelWidget = mainWindow->centralWidget();
    }

    /*父对象设置为顶层窗口*/
    Message* messageBox=new Message(topLevelWidget);
    messageBox->setMessage(msg);
    messageBox->setMsgType(type);
    messageBox->adjustSize();

    /*安装事件过滤器，随着窗口动,让Message监控topLevelWidget的事件*/
    topLevelWidget->installEventFilter(messageBox);

    messageBox->move(w->topLevelWidget()->width()/2-messageBox->width()/2,5);   /*移动至顶部中间*/
    messageBox->show();
}

void Message::showInfomation(const QString& msg,QWidget* w)
{
    showMessage(msg,MsgType::Info,w);
}
void Message::showWarning(const QString& msg,QWidget* w)
{
    showMessage(msg,MsgType::Warning,w);
}
void Message::showCritical(const QString& msg,QWidget* w)
{
    showMessage(msg,MsgType::Critical,w);
}

QString Message::toString(MsgType type)
{
    switch (type)
    {
#define CREATE_CASE(E,S,C1,C2,C3) case MsgType::E:return S;
    FOR_ALL_MSG_TYPE(CREATE_CASE)
#undef CREATE_CASE
    }
    return toString(MsgType::Unknow);
}

QColor Message::fontColor(MsgType type)
{
    switch (type)
    {
#define CREATE_COLOR(E,S,C1,C2,C3) case MsgType::E:{ return C3;}
    FOR_ALL_MSG_TYPE(CREATE_COLOR)
#undef CREATE_COLOR
    }
    return fontColor(MsgType::Unknow);
}

QColor Message::backgroundColor(MsgType type)
{
    switch (type)
    {
#define CREATE_COLOR(E,S,C1,C2,C3) case MsgType::E:{ return C2;}
    FOR_ALL_MSG_TYPE(CREATE_COLOR)
#undef CREATE_COLOR
    }
    return backgroundColor(MsgType::Unknow);
}

void Message::setOpacity(qreal opacity)
{
    m_opacity=opacity;
    m_button->setOpacity(m_opacity);
    m_typeLabel->setOpacity(m_opacity);
    update();
}

qreal Message::getOpacity() const
{
    return m_opacity;
}

void Message::setMsgType(MsgType msgType)
{
    m_msgType=msgType;
    m_button->setMsgType(m_msgType);
    m_typeLabel->setMsgType(m_msgType);

    /*设置字体颜色*/
    QPalette pal=m_label->palette();
    pal.setColor(QPalette::WindowText,fontColor(m_msgType));
    m_label->setPalette(pal);

    /**/
    m_typeLabel->setText(toString(m_msgType));
}
MsgType Message::getMsgType() const
{
    return m_msgType;
}

void Message::setMessage(const QString& msg)
{
    m_label->setText(msg);
}

QString Message::getMessage() const
{
    return m_label->text();
}


